package cn.edu.ren.hystrix;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @PackageName: cn.edu.ren.hystrix
 * @ClassName: MyHystrixCommand
 * @Description:
 * @author: RZS
 * @date: 2021/6/26  23:59
 */
public class MyHystrixCommand extends HystrixCommand<String> {

    private final String name;

    /*public MyHystrixCommand(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("MyGroup"));
        this.name = name;
    }*/

    // 信号隔离
    /*public MyHystrixCommand(String name) {
        super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE
                        )));
        this.name = name;
    }*/

    // 线程隔离
    public MyHystrixCommand(String name) {
        super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10)
                        .withMaxQueueSize(100).withMaximumSize(100)));
        this.name = name;
    }


    @Override
    protected String run() throws Exception {

        System.err.println("get data");
        return this.name + ":" + Thread.currentThread().getName();
    }

    /*@Override
    protected String run() {
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return this.name + ":" + Thread.currentThread().getName();
    }*/

    @Override
    protected String getFallback() {
        return "失败了 ";
    }

    /**
     * 在 Hystrix 中也为我们提供了方法级别的缓存。通过重写 getCacheKey 来判断是否返回缓存的数据，
     * getCacheKey 可以根据参数来生成。这样，同样的参数就可以都用到缓存了。
     * @return
     */
    @Override
    protected String getCacheKey() {
        return String.valueOf(this.name);
    }


   /* public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 同步调用
        String result = new MyHystrixCommand("zhangsan").execute();
        System.out.println(result);

        // 异步调用
        Future<String> future = new MyHystrixCommand("zhangsan").queue();
        System.out.println(future.get());
    }*/

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        String result = new MyHystrixCommand("zhangsan").execute();
        System.out.println(result);
        Future<String> future = new MyHystrixCommand("zhangsan").queue();
        System.out.println(future.get());
        context.shutdown();
    }
}
